﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using log4net;
using System.Configuration;
using Iudicium.Seguridad;
using Iudicium.Seguridad.CRN;

namespace Iudicium.Autenticacion
{
    /// <summary>
    /// Descripción breve de Seguridad
    /// </summary>
    public class Autenticacion
    {
        private static readonly ILog log = LogManager.GetLogger("LogFile");

        public static bool IsAuthenticate()
        {

            HttpCookie cookie = HttpContext.Current.Request.Cookies["UserInfo"];
            bool isTrue = (cookie != null && cookie["UserName"] != null &&
                cookie["RolId"] != null && cookie["UserId"] != null);
            if (isTrue)
            {
                cookie.Expires = DateTime.Now.AddMinutes(GetTimeOut());
                HttpContext.Current.Response.SetCookie(cookie);
            }
            return isTrue;
        }

        public static bool Autenticar(string userName, string password, ref string mensaje)
        {

            if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
            {
                mensaje = "Debe ingresar su usuario y su contraseña.";
                return false;
            }
            password = Utilitarios.Utilitarios.Encriptar(password);

            Usuario user = null;

            try
            {
                user = Iudicium.Seguridad.CRN.UsuarioCRN.GetUsuarioByUserNameAndPassword(userName);
            }
            catch (Exception ex)
            {
                log.Error("No se pudo obtener el usuario", ex);
            }

            if (user == null)
            {
                mensaje = "El nombre de usuario ingresado no existe.";
                return false;
            }

            if (user.Estado == Usuario.EstadoUsuario.Inactivo)
            {
                mensaje = "El usuario se encuentra inactivo.";
                return false;
            }
            if (!password.Equals(user.Passsword))
            {
                mensaje = "La contraseña ingresada es incorrecta.";
                return false;
            }
            Rol rol = null;
            try
            {
                rol = RolCRN.GetRolById(user.RolId);
            }
            catch (Exception ex)
            {
                log.Error("No se pudo obtener el rol del usuario con ind " + user.UsuarioId , ex);
            }
            if (rol == null || rol.Estado == Rol.EstadoRol.Inactivo)
            {
                mensaje = "El usuario se encuentra inactivo.";
                return false;
            }
            HttpCookie cookie = new HttpCookie("UserInfo");
            cookie["UserName"] = user.NombreUsuario;
            cookie["RolId"] = user.RolId.ToString();
            cookie["UserId"] = user.UsuarioId.ToString();
            cookie.Expires = DateTime.Now.AddMinutes(GetTimeOut());
            HttpContext.Current.Response.SetCookie(cookie);

            mensaje = "";
            return true;
        }

        public static void Desautenticar()
        {
            HttpCookie cookie = new HttpCookie("UserInfo");
            cookie.Expires = DateTime.Now.AddDays(-360);
            HttpContext.Current.Response.SetCookie(cookie);
        }

        private static int GetTimeOut()
        {
            int timeOut = 30;

            try
            {
                timeOut = Convert.ToInt32(ConfigurationManager.AppSettings["SessionTimeOut"]);
            }
            catch(Exception ex)
            {
                log.Error("No se pudo obtener el tiempo de expiracion de la configuracion", ex);
            }
            return timeOut;
        }

        public static string GetCurrentUserFullName()
        {
            if (!IsAuthenticate())
                return "";
            string name = "";
            try
            {
                Iudicium.Persona.PersonaNatural obj = Iudicium.Persona.CRN.PersonaNaturalCRN.GetPersonaNaturalById(GetCurrentUserId());
                name = obj == null ? "" : obj.Nombre;
            }
            catch (Exception ex)
            {
                log.Error("No se pudo obtener el nombre completo del usuario actual del cookie", ex);
                name = "";
            }
            return name;
        }

        public static int GetCurrentUserId()
        {
            if (!IsAuthenticate())
                return 0;
            HttpCookie cookie = HttpContext.Current.Request.Cookies["UserInfo"];
            if (cookie == null || cookie["UserId"] == null)
                return 0;
            int userId = 0;
            try
            {
                userId = Convert.ToInt32(cookie["UserId"]);
            }
            catch (Exception ex)
            {
                log.Error("No se pudo obtener el id del usuario actual del cookie",ex);
                userId = 0;
            }
            return userId;
        }

        public static int GetCurrentRolId()
        {
            if (!IsAuthenticate())
                return 0;
            HttpCookie cookie = HttpContext.Current.Request.Cookies["UserInfo"];
            if (cookie == null || cookie["RolId"] == null)
                return 0;
            int rolId = 0;
            try
            {
                rolId = Convert.ToInt32(cookie["RolId"]);
            }
            catch (Exception ex)
            {
                log.Error("No se pudo obtener el rolid del usuario actual del cookie", ex);
                rolId = 0;
            }
            return rolId;
        }

        public static bool TienePermisos(string nombrePermiso)
        {
            if (!IsAuthenticate())
                return false;
            bool have = false;
            try
            {
                have = Iudicium.Seguridad.CRN.PermisoCRN.UsuarioTienePermiso(nombrePermiso, GetCurrentUserId());
            }
            catch(Exception ex)
            {
                log.Error("No se pudo determinar si el usuario actual tiene el permiso especificado",ex);
            }
            return have;
        }
    }
}
